iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 10
1

前言

不知不覺就來到第十天了,今明兩天要來談談怎麼在 Shell 中存取(set and get)環境變數,之前只有簡單帶過,今天來認真介紹一下

環境變數

在 Unix Like 系統中,每個 Process 都有自己的環境變數,而且環境變數會傳給自己的 Child Process,所以由 Shell 產生出來的 Child Process 也會繼承到 Shell 的環境變數

在 Shell 中想看某個變數值可以下指令 echo $VAR 或是 echo ${VAR},後者可以再接其他字串譬如說 echo ${SHELL}HelloWorld

如果想看目前環境中的所有變數可以下 env,常見的 PWDSHELLPATH 都在裡面

今日目標

目前 Gosh 還沒有取得環境變數的功能,因為它不知道 $SHELL 是一個環境變數,只是很單純的輸出 $SHELL 字串(好笨的 Shell ?)

若要讓 Gosh 成功輸出環境變數必須在 Shell 裡面替換掉字串才行

實作

會用到的 function

  • os.ExpandEnv(str string)

    讀取環境變數也是個 System Call,但 ExpandEnv 已經把 System Call 包裝好了,他可以直接把字串中的 $VAR${VAR} 替換成環境變數,譬如說把 echo ${USER} 展開成 echo larry

executeInput

func executeInput(input string) error {
    // 把 input 裡面的環境變數展開
    // 如果指令是 echo ${USER}_is_smart
    // 展開後就會變成 echo larry_is_smart
    input = os.ExpandEnv(input)

    args := strings.Split(input, " ")

    // ...

    err := cmd.Run()
    return err
}

實作起來超簡單,因為 Go 已經把很多雜事都處理好,不然原本要先自己取得變數再替換 $VAR${VAR}

Demo

在 Gosh 中輸出 SHELLPWDUSER

小結

今天的內容很簡單,就只是把指令中的環境變數都展開來,程式碼放在這裡,有什麼問題歡迎在下面提問(今天這麼簡單應該不會有吧XD),沒問題的話明天就來實作存取環境變數中 的部分

延伸閱讀


上一篇
Day09-內建指令
下一篇
Day11-存取環境變數(二)
系列文
Gosh!原來用 Go 寫一個 Unix Shell 這麼簡單30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
jjlayyl
iT邦新手 5 級 ‧ 2019-10-05 23:19:02

對了~有個小小的問題
為什麼在讀std的時候不用這個方法呢?

stdin := bufio.NewReader(os.Stdin)
fmt.Println(">")
input, perf, err := stdin.ReadLine()

問得很好XD,我當初也想了很久到底要用哪個,但後來看到 ReadLine 的說明裡面有寫到

If the line was too long for the buffer then isPrefix is set and the beginning of the line is returned. The rest of the line will be returned from future calls.

意思是說他不保證可以讀取到整行,如果沒有讀取到完整的一行,那就要再 call 一次 ReadLine 拿到後半段

ReadString 的說明是

ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter.

意思是 ReadString('\n') 會一直往後讀直到 \n 出現,可以保證讀取到完整的一行,所以就果斷用 ReadString 了XD

我要留言

立即登入留言